//
//  NSObject+MKAPI.h
//  MKAPI
//
//  Created by 苏尚进 on 2022/7/30.
//  Copyright © 2022 moon. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
@interface NSDictionary (MKAPI)
- (nullable id)mkapi_objectForKeyPath:(NSString *)keyPath;
@end

@interface NSMutableDictionary (MKAPI)
- (void)mkapi_setObject:(nullable id)obj forKeyPath:(NSString *)keyPath;
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSArray (MKAPI)
- (nullable id)mkapi_objectForKeyPath:(NSString *)keyPath;
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSString(MKAPI_UrlEndecode)
@property(nonatomic,readonly) NSString *mkapi_urlEncode;//进行urlencode
@property(nonatomic,readonly) NSString *mkapi_urlDecode;//进行urldecode
@property(nonatomic,readonly) NSString *mkapi_contentTypeForPathExtension;//将文件名后缀转换为mime值
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSString (MKAPIHttpsSecurity)

/// 返回PEM格式的证书二进制对象，输入的PEM证书形如：
/*
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
 
 网站证书查看工具：https://myssl.com/ssl.html
 */
/// 处理过程为，截取-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----中间的字符串，然后将空白符（换行、tab、空格等）去掉，得到最终字符串（该字符串为base64后的数据）
@property(nonatomic,readonly,nullable) NSString *mkapi_secPemString;
@property(nonatomic,readonly) NSArray<NSString *> *mkapi_secPemStringArray;

/// 对mkapi_secPemString后的数据，进行base64 decode操作
@property(nonatomic,readonly,nullable) NSData *mkapi_secPemData;
@property(nonatomic,readonly) NSArray<NSData *> *mkapi_secPemDataArray;

/// 输入SecTrustRef证书链的可阅读信息，格式为证书的CN字段，多个以|分隔，如：httpbingo.org|R3|ISRG Root X1
/// @param serverTrust 证书链
+ (nullable NSString *)mkapi_stringWithSecTrustRef:(SecTrustRef)serverTrust;
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSURLSessionTask(MKAPIHttpRequestAFNetworking)
@property(nonatomic,assign) BOOL mkapi_didEvaluateServerTrust;//是否验证过ssl证书，用于防止ssl证书绕过越狱插件（原理是拦截系统的证书检验方法，直接通过检验）
@property(nonatomic,strong,nullable) NSURLAuthenticationChallenge *mkapi_authenticationChallenge;//ssl证书检验过程的证书链信息,通过challenge.protectionSpace.serverTrust，可以获取到证书链
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSDictionary (MKAPIURL)
@property(nonatomic,readonly) NSString *mkapi_keyValuesUrlEncode;//输出urlencode的字符串，如 k1=v1&k2[]=v2&k2[]=v22&k3[a1]=v3&k3[a2]=v33
- (NSString *)mkapi_urlQueryStringWithUrlEncode:(BOOL)urlEncode;//输出urlencode的字符串，如 k1=v1&k2[]=v2&k2[]=v22&k3[a1]=v3&k3[a2]=v33
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSString(MKAPIURL)

/// 解析NSURL的query参数，变成NSDictionary对象。value可能为NSString，NSArray（key格式为key[])，NSDictionary(key格式为key[subkey])，NSSet(含有同名的key)
/// - Parameter urlDecode: 是否对参数值进行urldecode操作
/* 例：参数字符串为k1=a&k2&k3=&sameKey=1&sameKey=2&sameKey&list[]=a&list[]=b&list[]&dict[k1]=1&dict[k2]=2&dict[k3]&zh1=中文&zh2=%E4%B8%AD%E6%96%87&base64Key=MDE=
 urlDecode为YES，则解析出来的dict为：
 {
    "k1":"a",
    "k2":"",
    "k3":"",
    "zh1":"中文",
    "zh2":"中文",
    "sameKey":["1","2",""],
    "list":["a","b",""],
    "dict":{
        "k1":"1",
        "k2":"2",
        "k3":""
    },
    "base64Key":"MDE="//当有多个=号时，取第一个=号作为key、value的分隔符
 }
 */
- (NSDictionary<NSString *,id> *)mkapi_NSURLQueryItemsWithUrlDecode:(BOOL)urlDecode;

/// 解析NSURL的query参数，变成NSDictionary对象
/// - Parameter urlDecode: 是否对参数值进行urldecode操作
/* 例：参数字符串为k1=a&k2&k3=&sameKey=1&sameKey=2&sameKey&list[]=a&list[]=b&list[]&dict[k1]=1&dict[k2]=2&dict[k3]&zh1=中文&zh2=%E4%B8%AD%E6%96%87&base64Key=MDE=
 urlDecode为YES，则解析出来的dict为：
 {
    "k1":"a",
    "k2":"",
    "k3":"",//=后面取空时，值为""字符串
    "zh1":"中文",
    "zh2":"中文",
    "sameKey":"",//sameKey有重复的，将取最后一个值
    "list[]":"",//list[]有重复的，将取最后一个值
    "dict[k1]":"1",
    "dict[k2]":"2",
    "dict[k3]":"",
    "base64Key":"MDE="//当有多个=号时，取第一个=号作为key、value的分隔符
 }
*/
- (NSDictionary<NSString *,NSString *> *)mkapi_NSURLQueryDictionaryWithUrlDecode:(BOOL)urlDecode;

/// 等效于[self mkapi_NSURLQueryDictionaryWithUrlDecode:YES];
@property(nonatomic,readonly) NSDictionary<NSString *,NSString *> *mkapi_NSURLQueryDictionary;
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSURLAuthenticationChallenge(MKAPI)

/// 验证ssl证书是否可信
/// - Parameter certs: 授信的证书列表。证书格式为PEM的二进制格式。参数NSString的mkapi_secPemData扩展方法
- (BOOL)mkapi_verifyServerTrustWithCerts:(NSArray<NSData *> *)certs;
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSData(MKAPI_Coder)
@property(nonatomic,readonly) NSString *mkapi_hexEncodedString;//输出16进制的小写字符串
@property(nonatomic,readonly) NSString *mkapi_base64EncodedString;//输出base64编码字符串
@end
@interface NSString(MKAPI_Coder)
@property(nonatomic,readonly,nullable) NSData *mkapi_hexDecodedData;//进行16进制解码
@property(nonatomic,readonly,nullable) NSData *mkapi_base64DecodedData;//进行base64解码
@end
@interface NSString(MKAPI_Desc)
+ (NSString *)mkapi_stringWithNSDataSize:(NSUInteger)size;//输出NSData的大小，如4Byte，12.2KB，103MB，1.1GB
@end
NS_ASSUME_NONNULL_END

NS_ASSUME_NONNULL_BEGIN
@interface NSString(MKAPI_JSON)
@property(nonatomic,readonly,nullable) id mkapi_jsonObject;
@property(nonatomic,readonly,nullable) NSDictionary *mkapi_jsonDictionary;
@property(nonatomic,readonly,nullable) NSArray *mkapi_jsonArray;
@end
@interface NSDictionary(MKAPI_JSON)
@property(nonatomic,readonly,nullable) NSString *mkapi_jsonString;
@end
@interface NSArray(MKAPI_JSON)
@property(nonatomic,readonly,nullable) NSString *mkapi_jsonString;
@end
NS_ASSUME_NONNULL_END
